#ifndef OPT_ASAN
#define OPT_ASAN
#include "llvm/IR/Function.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ADT/DenseMap.h"
#include <unordered_map>
#include <unordered_set>
#include <string>

class OptForAsan {
public:
    OptForAsan(llvm::DenseMap<const llvm::AllocaInst *, bool> &ProcessedAllocas);
    ~OptForAsan();
    llvm::DenseMap<const llvm::Instruction *, bool> ApplyOnFunc(llvm::Function &F, const llvm::TargetLibraryInfo *TLI);

private:
    bool DoFunctionExcludeOpt(llvm::Function &F);
    void DoStackSafeVariableOpt(llvm::Function &F);
    void DoHeapSafeVariableOpt(llvm::Function &F);

    // heap static
    void checkReleasedVar(llvm::Function &F);

private:
    std::unordered_map<std::string, bool> _unsafe_functions;
    llvm::DenseMap<const llvm::AllocaInst *, bool> &processAllocas;
    std::unordered_set<const llvm::Instruction *> _unintrested_insts;
    std::unordered_set<const llvm::Instruction *> _not_instrument;
};

#endif